package com.lambkit;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import com.jfinal.aop.Aop;
import com.jfinal.config.JFinalConfig;
import com.jfinal.server.undertow.UndertowConfig;
import com.jfinal.server.undertow.UndertowServer;
import com.jfinal.server.undertow.WebBuilder;
import com.lambkit.annotion.JFConfig;
import com.lambkit.cache.JFCacheFactory;
import com.lambkit.config.DefaultJFinalConfig;
import com.lambkit.core.Lambkit;
import com.lambkit.core.LambkitServer;
import com.lambkit.core.annotion.App;
import com.lambkit.core.pipeline.DefaultPipeLineFactory;
import com.lambkit.service.JFBeanFactory;
import com.lambkit.service.JFResourceFactory;
import com.lambkit.undertow.DefaultUndertowCallback;
import com.lambkit.undertow.JFUndertowServer;
import com.lambkit.undertow.UndertowCallback;

import java.util.function.Consumer;

/**
 * @author yangyong(孤竹行)
 */
@App(JFinalApp.class)
public class JFinalUndertowServer implements LambkitServer {
    TimeInterval timer = DateUtil.timer();
    private UndertowServer server;
    @Override
    public void start() {
        Lambkit.context().setBeanFactory(new JFBeanFactory());
        Lambkit.context().setPipeLineFactory(new DefaultPipeLineFactory());
        Lambkit.context().setResourceFactory(new JFResourceFactory());
        Lambkit.context().setCacheFactory(new JFCacheFactory());

        Class<? extends JFinalConfig> contextClass = null;
        Class<? extends UndertowCallback> undertowCallback = null;
        JFConfig JFConfig = Lambkit.context().getTargetClass().getAnnotation(JFConfig.class);
        if(JFConfig != null) {
            contextClass = JFConfig.value();
            undertowCallback = JFConfig.undertowCallback();
        }
        if(contextClass == null) {
            contextClass = DefaultJFinalConfig.class;
        }
        if(undertowCallback == null) {
            undertowCallback = DefaultUndertowCallback.class;
        }
        UndertowCallback callback = undertowCallback == null ? null : Aop.get(undertowCallback);
        server = createServer(new UndertowConfig(contextClass), callback);
        server.start();
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        System.out.println("JFLambkit Application Starting Complete in " + timer.interval() + "ms.");
    }

    @Override
    public void stop() {
        server.stop();
    }

    private UndertowServer createServer(UndertowConfig config, UndertowCallback undertowCallback) {
        //LambkitBeanManager.me().setServerType("undertow");
        //LambkitBeanManager.me().setPort(config.getPort());
        if(undertowCallback !=null) {
            undertowCallback.config(config);
        }
        Consumer<WebBuilder> webBuilder = builder->{
            if(undertowCallback !=null) {
                undertowCallback.configBuilder(builder);
            }
            // 配置 WebSocket，DefaultWebSocketServer 需使用 ServerEndpoint 注解
            //builder.addWebSocketEndpoint("com.lambkit.web.websocket.DefaultWebSocketServer");
        };
        return JFUndertowServer.create(config).configCallback(undertowCallback).configWeb(webBuilder);
    }
}
